using System;
using System.Text;

namespace MyCollections
{
    public class LinkedList<T>
    {
        private int _count;
        public LinkedListNode<T> First;
        public LinkedListNode<T> Last;

        public int Count
        {
            get { return _count; }
        }

        public LinkedList()
        {
            First = null;
            Last = null;
            _count = 0;
        }

        public void AddLast(LinkedListNode<T> newNode)
        {
            if (_count == 0)
            {
                First = newNode;
            }
            else
            {
                Last.Next = newNode;
                newNode.Previous = Last;
            }

            Last = newNode;
            newNode.List = this;
            _count++;
        }

        public LinkedListNode<T> Find(T item)
        {
            var current = First;

            while (current != null)
            {
                if (Equals(current.PayLoad, item))
                {
                    return current;
                }
                current = current.Next;

            }
            return null;
        }

        public void RemoveFirst()
        {
            if (_count == 0)
            {
                throw new InvalidOperationException();
            }

            if (_count == 1)
            {
                First = null;
                Last = null;
            }
            else
            {
                First.List = null;
                var tempNode = First.Next;
                First.Next = null;
                tempNode.Previous = null;
                First = tempNode;
            }
            _count--;

        }

        public string PrintForward()
        {
            var sb = new StringBuilder();
            var tekNode = First;
            while (tekNode != null)
            {
                sb=sb.Append(tekNode.PayLoad+"\n");
                tekNode = tekNode.Next;
            }
            return sb.ToString();
        }

        public LinkedListEnumerator<T> GetEnumerator()
        {
            return new LinkedListEnumerator<T>(this);
        }
    }
}